package com.geektime.config;

import com.alibaba.druid.filter.FilterChain;
import com.alibaba.druid.filter.FilterEventAdapter;
import com.alibaba.druid.proxy.jdbc.JdbcParameter;
import com.alibaba.druid.proxy.jdbc.PreparedStatementProxy;
import com.alibaba.druid.proxy.jdbc.ResultSetProxy;
import com.alibaba.druid.proxy.jdbc.StatementProxy;
import org.springframework.stereotype.Component;

import java.sql.SQLException;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class DruidFilter extends FilterEventAdapter {

    @Override
    public ResultSetProxy preparedStatement_executeQuery(FilterChain chain, PreparedStatementProxy statement) throws SQLException {
        String sql = statement.getSql();
        // 判断 sql 为批量处理的任务
        if(isBatchJob(sql)){
            throw new SQLException("Batch task execution is not allowed");
        }
        if(isOverInLimit(sql)){
            throw new SQLException("Exceeded the number of executions of the 'in' keyword");
        }
        return super.preparedStatement_executeQuery(chain, statement);
    }


    /**
     * 判断是否超过了"IN"关键字的使用限制
     * @return
     */
    public Boolean isOverInLimit(String sql){

        String pattern = "in\\s*\\((.+?)\\)";

        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(sql);
        if(m.find()){
            String inStr = m.group();
            return inStr.split(",").length > 8;
        }
        return false;
    }

    /**
     * 判断 sql 为批量处理的任务
     * @param sql
     * @return
     */
    public Boolean isBatchJob(String sql){
        String[] split = sql.split(";");
        if(split.length > 2) {
            return true;
        }
        if(split.length == 2){
            String strPart2 = split[1];
            strPart2 = strPart2.replace(" ", "");
            if(!strPart2.isEmpty()){
                return true;
            }
        }
        return false;
    }

}
